"""
聊天系统API接口
"""
from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException, Request, status
from sqlalchemy.orm import Session
from sqlalchemy import desc, not_
from typing import List
from utils.database import get_db
from utils import JWTUtils
from Models.chat.models import ChatRoom, ChatMessage
from Models.login.models import User, Role
from Models.chat.schemas import ChatMessageResponse, ChatRoomResponse, UserListResponse, MerchantRoomCreate, PlatformKefuRoomCreate
from Models.travel.models import Attraction, Order
from utils.redis_utils import get_redis
import json
import logging

logger = logging.getLogger(__name__)

router = APIRouter()


def get_current_user_id(request: Request) -> int:
    """从请求头获取当前用户ID"""
    authorization = request.headers.get("Authorization")
    if not authorization:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="未提供认证令牌"
        )
    
    token = authorization.replace("Bearer ", "").strip()
    payload = JWTUtils.decode_access_token(token)
    if not payload or not payload.get("user_id"):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="认证令牌无效"
        )
    return payload["user_id"]


@router.get("/rooms", response_model=List[ChatRoomResponse])
async def get_user_rooms(
    request: Request,
    db: Session = Depends(get_db)
):
    """获取用户的聊天房间列表（客服端）"""
    user_id = get_current_user_id(request)
    
    # 检查用户是否是平台客服
    user = db.query(User).filter(User.id == user_id).first()
    is_platform_kefu = False
    if user and user.role:
        is_platform_kefu = user.role.code == "platform_kefu"
    
    # 平台客服可以查看所有房间，其他客服只能查看分配给自己的房间
    if is_platform_kefu:
        rooms = db.query(ChatRoom).filter(
            ChatRoom.is_active == True
        ).order_by(desc(ChatRoom.updated_at)).all()
    else:
        rooms = db.query(ChatRoom).filter(
            ChatRoom.kefu_id == user_id,
            ChatRoom.is_active == True
        ).order_by(desc(ChatRoom.updated_at)).all()
    
    result = []
    for room in rooms:
        # 获取最后一条消息
        last_message = db.query(ChatMessage).filter(
            ChatMessage.room_id == room.room_id
        ).order_by(desc(ChatMessage.created_at)).first()
        
        room_dict = {
            "id": room.id,
            "room_id": room.room_id,
            "user_id": room.user_id,
            "kefu_id": room.kefu_id,
            "is_active": room.is_active,
            "created_at": room.created_at,
            "updated_at": room.updated_at,
            "last_message": None
        }
        
        if last_message:
            room_dict["last_message"] = ChatMessageResponse(
                id=last_message.id,
                room_id=last_message.room_id,
                sender_id=last_message.sender_id,
                sender_type=last_message.sender_type,
                message_type=last_message.message_type.value,
                content=last_message.content,
                created_at=last_message.created_at
            )
        
        result.append(ChatRoomResponse(**room_dict))
    
    return result


@router.get("/users", response_model=List[UserListResponse])
async def get_user_list(
    request: Request,
    db: Session = Depends(get_db)
):
    """获取待服务用户列表（客服端）"""
    user_id = get_current_user_id(request)
    
    # 检查用户是否是平台客服
    user = db.query(User).filter(User.id == user_id).first()
    is_platform_kefu = False
    if user and user.role:
        is_platform_kefu = user.role.code == "platform_kefu"
    
    # 获取所有平台客服用户的ID，用于过滤（排除平台客服自己作为用户的情况）
    platform_kefu_role = db.query(Role).filter(Role.code == "platform_kefu").first()
    platform_kefu_user_ids = []
    if platform_kefu_role:
        platform_kefu_users = db.query(User).filter(User.role_id == platform_kefu_role.id).all()
        platform_kefu_user_ids = [u.id for u in platform_kefu_users]
    
    # 平台客服可以查看所有用户，其他客服只能查看未分配的用户
    # 显示所有有聊天房间的用户（包括kefu和merchant类型）
    # 排除 user_id 是平台客服的房间（平台客服不应该作为用户出现在列表中）
    base_filter = [
        ChatRoom.is_active == True
    ]
    
    # 如果有平台客服用户ID，添加排除条件
    if platform_kefu_user_ids:
        base_filter.append(not_(ChatRoom.user_id.in_(platform_kefu_user_ids)))
    
    if is_platform_kefu:
        # 平台客服可以查看所有房间（kefu和merchant类型）
        rooms = db.query(ChatRoom).filter(*base_filter).all()
    else:
        # 其他客服只能查看未分配的kefu类型房间
        base_filter.extend([
            ChatRoom.kefu_id.is_(None),
            ChatRoom.room_type == "kefu"
        ])
        rooms = db.query(ChatRoom).filter(*base_filter).all()
    
    # 使用字典存储每个用户的最新房间信息，避免重复
    user_rooms = {}
    
    for room in rooms:
        user = db.query(User).filter(User.id == room.user_id).first()
        if not user:
            continue
        
        # 再次检查：如果用户是平台客服，跳过（双重保险）
        if user.role and user.role.code == "platform_kefu":
            continue
        
        # 获取最后一条消息
        last_message = db.query(ChatMessage).filter(
            ChatMessage.room_id == room.room_id
        ).order_by(desc(ChatMessage.created_at)).first()
        
        # 确定房间的排序时间（优先使用最后一条消息的时间，否则使用房间更新时间）
        room_time = last_message.created_at if last_message else room.updated_at
        
        # 如果该用户还没有记录，或者当前房间更新，则更新记录
        if user.id not in user_rooms:
            user_rooms[user.id] = {
                "room": room,
                "user": user,
                "last_message": last_message,
                "room_time": room_time
            }
        else:
            # 如果当前房间有更新的消息，则替换
            if room_time and user_rooms[user.id]["room_time"]:
                if room_time > user_rooms[user.id]["room_time"]:
                    user_rooms[user.id] = {
                        "room": room,
                        "user": user,
                        "last_message": last_message,
                        "room_time": room_time
                    }
            elif room_time and not user_rooms[user.id]["room_time"]:
                # 当前房间有消息，之前没有，使用当前房间
                user_rooms[user.id] = {
                    "room": room,
                    "user": user,
                    "last_message": last_message,
                    "room_time": room_time
                }
    
    # 构建返回结果
    result = []
    for user_id, data in user_rooms.items():
        room = data["room"]
        user = data["user"]
        last_message = data["last_message"]
        
        user_dict = {
            "user_id": user.id,
            "username": user.username or f"用户{user.id}",
            "nickname": user.nickname,
            "avatar": user.avatar,
            "room_id": room.room_id,
            "unread_count": 0,
            "last_message": None
        }
        
        if last_message:
            user_dict["last_message"] = ChatMessageResponse(
                id=last_message.id,
                room_id=last_message.room_id,
                sender_id=last_message.sender_id,
                sender_type=last_message.sender_type,
                message_type=last_message.message_type.value,
                content=last_message.content,
                created_at=last_message.created_at
            )
        
        result.append(UserListResponse(**user_dict))
    
    # 按最后消息时间排序（最新的在前）
    result.sort(key=lambda x: x.last_message.created_at if x.last_message else datetime.min, reverse=True)
    
    return result


@router.get("/my-room", response_model=ChatRoomResponse)
async def get_my_room(
    request: Request,
    db: Session = Depends(get_db)
):
    """获取用户自己的房间信息（用户端）"""
    user_id = get_current_user_id(request)
    
    # 获取用户的房间
    room_id = f"user{user_id}"
    room = db.query(ChatRoom).filter(ChatRoom.room_id == room_id).first()
    
    if not room:
        # 如果房间不存在，创建一个
        room = ChatRoom(
            room_id=room_id,
            user_id=user_id,
            kefu_id=None
        )
        db.add(room)
        db.commit()
        db.refresh(room)
    
    # 获取最后一条消息
    last_message = db.query(ChatMessage).filter(
        ChatMessage.room_id == room.room_id
    ).order_by(desc(ChatMessage.created_at)).first()
    
    room_dict = {
        "id": room.id,
        "room_id": room.room_id,
        "user_id": room.user_id,
        "kefu_id": room.kefu_id,
        "is_active": room.is_active,
        "created_at": room.created_at,
        "updated_at": room.updated_at,
        "last_message": None
    }
    
    if last_message:
        room_dict["last_message"] = ChatMessageResponse(
            id=last_message.id,
            room_id=last_message.room_id,
            sender_id=last_message.sender_id,
            sender_type=last_message.sender_type,
            message_type=last_message.message_type.value,
            content=last_message.content,
            created_at=last_message.created_at
        )
    
    return ChatRoomResponse(**room_dict)


@router.post("/assign/{room_id}")
async def assign_kefu(
    room_id: str,
    request: Request,
    db: Session = Depends(get_db)
):
    """分配客服到用户房间"""
    kefu_id = get_current_user_id(request)
    
    # 获取房间
    room = db.query(ChatRoom).filter(ChatRoom.room_id == room_id).first()
    if not room:
        raise HTTPException(status_code=404, detail="房间不存在")
    
    if room.kefu_id:
        raise HTTPException(status_code=400, detail="该房间已分配客服")
    
    # 分配客服
    room.kefu_id = kefu_id
    db.commit()
    
    return {"message": "分配成功", "room_id": room_id, "kefu_id": kefu_id}


@router.get("/messages/{room_id}", response_model=List[ChatMessageResponse])
async def get_history_messages(
    room_id: str,
    limit: int = 50,
    request: Request = None,
    db: Session = Depends(get_db)
):
    """获取历史消息"""
    user_id = get_current_user_id(request)
    
    # 检查权限：用户只能看自己的房间，客服可以看分配给他的房间，平台客服可以看所有房间
    room = db.query(ChatRoom).filter(ChatRoom.room_id == room_id).first()
    if not room:
        raise HTTPException(status_code=404, detail="房间不存在")
    
    # 检查用户是否是平台客服
    user = db.query(User).filter(User.id == user_id).first()
    is_platform_kefu = False
    if user and user.role:
        is_platform_kefu = user.role.code == "platform_kefu"
    
    # 权限检查：平台客服可以访问所有房间，其他用户只能访问自己的房间或分配给他们的房间
    if not is_platform_kefu:
        if room.user_id != user_id and room.kefu_id != user_id and room.merchant_id != user_id:
            raise HTTPException(status_code=403, detail="无权访问该房间")
    
    # 先从Redis获取
    redis_client = get_redis()
    redis_key = f"chat_history:{room_id}"
    redis_messages = redis_client.lrange(redis_key, -limit, -1)
    
    messages = []
    if redis_messages:
        # 从Redis读取
        for msg_json in redis_messages:
            try:
                msg_dict = json.loads(msg_json)
                messages.append(ChatMessageResponse(**msg_dict))
            except:
                pass
    
    # 如果Redis数据不足，从数据库补充
    if len(messages) < limit:
        db_messages = db.query(ChatMessage).filter(
            ChatMessage.room_id == room_id
        ).order_by(desc(ChatMessage.created_at)).limit(limit - len(messages)).all()
        
        for msg in reversed(db_messages):
            msg_dict = {
                "id": msg.id,
                "room_id": msg.room_id,
                "sender_id": msg.sender_id,
                "sender_type": msg.sender_type,
                "message_type": msg.message_type.value,
                "content": msg.content,
                "created_at": msg.created_at
            }
            messages.insert(0, ChatMessageResponse(**msg_dict))
    
    return messages[:limit]


@router.post("/merchant/create-room", response_model=ChatRoomResponse)
async def create_merchant_room(
    request_data: MerchantRoomCreate,
    request: Request,
    db: Session = Depends(get_db)
):
    """创建或获取商户聊天房间（用户端）"""
    try:
        user_id = get_current_user_id(request)
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=401, detail=f"认证失败: {str(e)}")
    
    try:
        # 获取商家ID
        merchant_id = None
        attraction_id = request_data.attraction_id
        order_id = request_data.order_id
        
        if attraction_id:
            # 从景点获取商家ID
            attraction = db.query(Attraction).filter(Attraction.id == attraction_id).first()
            if not attraction:
                raise HTTPException(status_code=404, detail=f"景点不存在 (ID: {attraction_id})")
            if not attraction.merchant_id:
                raise HTTPException(
                    status_code=400, 
                    detail=f"该景点暂无商家 (景点: {attraction.name}, ID: {attraction_id})"
                )
            merchant_id = attraction.merchant_id
            room_id = f"merchant_{merchant_id}_attraction_{attraction_id}_user_{user_id}"
        elif order_id:
            # 从订单获取商家ID
            order = db.query(Order).filter(Order.id == order_id).first()
            if not order:
                raise HTTPException(status_code=404, detail=f"订单不存在 (ID: {order_id})")
            if order.user_id != user_id:
                raise HTTPException(status_code=403, detail="无权访问该订单")
            attraction = db.query(Attraction).filter(Attraction.id == order.attraction_id).first()
            if not attraction:
                raise HTTPException(
                    status_code=400, 
                    detail=f"订单关联的景点不存在 (订单ID: {order_id}, 景点ID: {order.attraction_id})"
                )
            if not attraction.merchant_id:
                raise HTTPException(
                    status_code=400, 
                    detail=f"该订单关联的景点暂无商家 (景点: {attraction.name}, 订单ID: {order_id})"
                )
            merchant_id = attraction.merchant_id
            room_id = f"merchant_{merchant_id}_order_{order_id}_user_{user_id}"
        else:
            raise HTTPException(
                status_code=400, 
                detail="必须提供attraction_id或order_id"
            )
        
        # 查找或创建房间
        room = db.query(ChatRoom).filter(ChatRoom.room_id == room_id).first()
        if not room:
            try:
                room = ChatRoom(
                    room_id=room_id,
                    user_id=user_id,
                    merchant_id=merchant_id,
                    room_type="merchant",
                    attraction_id=attraction_id,
                    order_id=order_id
                )
                db.add(room)
                db.commit()
                db.refresh(room)
            except Exception as db_error:
                db.rollback()
                raise HTTPException(
                    status_code=500,
                    detail=f"创建聊天房间失败: {str(db_error)}"
                )
        
        # 获取最后一条消息
        last_message = db.query(ChatMessage).filter(
            ChatMessage.room_id == room.room_id
        ).order_by(desc(ChatMessage.created_at)).first()
        
        room_dict = {
            "id": room.id,
            "room_id": room.room_id,
            "user_id": room.user_id,
            "kefu_id": room.kefu_id,
            "merchant_id": room.merchant_id,
            "room_type": room.room_type or "merchant",
            "attraction_id": room.attraction_id,
            "order_id": room.order_id,
            "is_active": room.is_active if room.is_active is not None else True,
            "created_at": room.created_at,
            "updated_at": room.updated_at,
            "last_message": None
        }
        
        if last_message:
            room_dict["last_message"] = ChatMessageResponse(
                id=last_message.id,
                room_id=last_message.room_id,
                sender_id=last_message.sender_id,
                sender_type=last_message.sender_type,
                message_type=last_message.message_type.value,
                content=last_message.content,
                created_at=last_message.created_at
            )
        
        return ChatRoomResponse(**room_dict)
    except HTTPException:
        raise
    except Exception as e:
        import traceback
        error_detail = traceback.format_exc()
        logger.error(f"创建商户聊天房间失败: {error_detail}")
        raise HTTPException(
            status_code=500,
            detail=f"服务器内部错误: {str(e)}"
        )


@router.post("/platform-kefu/create-room", response_model=ChatRoomResponse)
async def create_platform_kefu_room(
    request_data: PlatformKefuRoomCreate,
    request: Request,
    db: Session = Depends(get_db)
):
    """创建或获取平台客服聊天房间（用户端）"""
    try:
        user_id = get_current_user_id(request)
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=401, detail=f"认证失败: {str(e)}")
    
    try:
        # 获取平台客服ID（从配置或数据库查询）
        from Models.login.models import Role
        platform_kefu_id = None
        
        # 查询平台客服角色
        platform_kefu_role = db.query(Role).filter(Role.code == "platform_kefu").first()
        
        if platform_kefu_role:
            # 查找属于平台客服角色的用户
            platform_kefu_user = db.query(User).filter(User.role_id == platform_kefu_role.id).first()
            if platform_kefu_user:
                platform_kefu_id = platform_kefu_user.id
        
        # 如果没有找到，尝试查找角色代码为"kefu"的用户
        if not platform_kefu_id:
            kefu_role = db.query(Role).filter(Role.code == "kefu").first()
            if kefu_role:
                kefu_user = db.query(User).filter(User.role_id == kefu_role.id).first()
                if kefu_user:
                    platform_kefu_id = kefu_user.id
        
        if not platform_kefu_id:
            # 如果还没有，创建一个默认的平台客服用户（使用ID=1作为占位符，实际应该通过初始化脚本创建）
            raise HTTPException(
                status_code=503,
                detail="平台客服暂未配置，请联系管理员"
            )
        
        # 生成房间ID
        room_id = f"platform_kefu_user_{user_id}"
        
        # 查找或创建房间
        room = db.query(ChatRoom).filter(ChatRoom.room_id == room_id).first()
        if not room:
            try:
                room = ChatRoom(
                    room_id=room_id,
                    user_id=user_id,
                    kefu_id=platform_kefu_id,
                    room_type="kefu",
                    merchant_id=None,
                    attraction_id=None,
                    order_id=None
                )
                db.add(room)
                db.commit()
                db.refresh(room)
            except Exception as db_error:
                db.rollback()
                raise HTTPException(
                    status_code=500,
                    detail=f"创建聊天房间失败: {str(db_error)}"
                )
        else:
            # 如果房间已存在但客服未分配，则分配平台客服
            if not room.kefu_id:
                room.kefu_id = platform_kefu_id
                db.commit()
                db.refresh(room)
        
        # 获取最后一条消息
        last_message = db.query(ChatMessage).filter(
            ChatMessage.room_id == room.room_id
        ).order_by(desc(ChatMessage.created_at)).first()
        
        room_dict = {
            "id": room.id,
            "room_id": room.room_id,
            "user_id": room.user_id,
            "kefu_id": room.kefu_id,
            "merchant_id": room.merchant_id,
            "room_type": room.room_type or "kefu",
            "attraction_id": room.attraction_id,
            "order_id": room.order_id,
            "is_active": room.is_active if room.is_active is not None else True,
            "created_at": room.created_at,
            "updated_at": room.updated_at,
            "last_message": None
        }
        
        if last_message:
            room_dict["last_message"] = ChatMessageResponse(
                id=last_message.id,
                room_id=last_message.room_id,
                sender_id=last_message.sender_id,
                sender_type=last_message.sender_type,
                message_type=last_message.message_type.value,
                content=last_message.content,
                created_at=last_message.created_at
            )
        
        return ChatRoomResponse(**room_dict)
    except HTTPException:
        raise
    except Exception as e:
        import traceback
        error_detail = traceback.format_exc()
        logger.error(f"创建平台客服聊天房间失败: {error_detail}")
        raise HTTPException(
            status_code=500,
            detail=f"服务器内部错误: {str(e)}"
        )


@router.get("/merchant/rooms", response_model=List[ChatRoomResponse])
async def get_merchant_rooms(
    request: Request,
    db: Session = Depends(get_db)
):
    """获取商户的聊天房间列表（商户端）"""
    merchant_id = get_current_user_id(request)
    
    # 获取该商户的所有房间
    rooms = db.query(ChatRoom).filter(
        ChatRoom.merchant_id == merchant_id,
        ChatRoom.room_type == "merchant",
        ChatRoom.is_active == True
    ).order_by(desc(ChatRoom.updated_at)).all()
    
    result = []
    for room in rooms:
        # 获取最后一条消息
        last_message = db.query(ChatMessage).filter(
            ChatMessage.room_id == room.room_id
        ).order_by(desc(ChatMessage.created_at)).first()
        
        room_dict = {
            "id": room.id,
            "room_id": room.room_id,
            "user_id": room.user_id,
            "kefu_id": room.kefu_id,
            "merchant_id": room.merchant_id,
            "room_type": room.room_type,
            "attraction_id": room.attraction_id,
            "order_id": room.order_id,
            "is_active": room.is_active,
            "created_at": room.created_at,
            "updated_at": room.updated_at,
            "last_message": None
        }
        
        if last_message:
            room_dict["last_message"] = ChatMessageResponse(
                id=last_message.id,
                room_id=last_message.room_id,
                sender_id=last_message.sender_id,
                sender_type=last_message.sender_type,
                message_type=last_message.message_type.value,
                content=last_message.content,
                created_at=last_message.created_at
            )
        
        result.append(ChatRoomResponse(**room_dict))
    
    return result


@router.get("/merchant/my-rooms", response_model=List[ChatRoomResponse])
async def get_my_merchant_rooms(
    request: Request,
    db: Session = Depends(get_db)
):
    """获取用户与商户的聊天房间列表（用户端）"""
    user_id = get_current_user_id(request)
    
    # 获取该用户的所有商户聊天房间
    rooms = db.query(ChatRoom).filter(
        ChatRoom.user_id == user_id,
        ChatRoom.room_type == "merchant",
        ChatRoom.is_active == True
    ).order_by(desc(ChatRoom.updated_at)).all()
    
    result = []
    for room in rooms:
        # 获取最后一条消息
        last_message = db.query(ChatMessage).filter(
            ChatMessage.room_id == room.room_id
        ).order_by(desc(ChatMessage.created_at)).first()
        
        room_dict = {
            "id": room.id,
            "room_id": room.room_id,
            "user_id": room.user_id,
            "kefu_id": room.kefu_id,
            "merchant_id": room.merchant_id,
            "room_type": room.room_type,
            "attraction_id": room.attraction_id,
            "order_id": room.order_id,
            "is_active": room.is_active,
            "created_at": room.created_at,
            "updated_at": room.updated_at,
            "last_message": None
        }
        
        if last_message:
            room_dict["last_message"] = ChatMessageResponse(
                id=last_message.id,
                room_id=last_message.room_id,
                sender_id=last_message.sender_id,
                sender_type=last_message.sender_type,
                message_type=last_message.message_type.value,
                content=last_message.content,
                created_at=last_message.created_at
            )
        
        result.append(ChatRoomResponse(**room_dict))
    
    return result


@router.delete("/room/{room_id}")
async def delete_room(
    room_id: str,
    request: Request,
    db: Session = Depends(get_db)
):
    """删除房间（仅平台客服可用）"""
    user_id = get_current_user_id(request)
    
    # 检查用户是否是平台客服
    user = db.query(User).filter(User.id == user_id).first()
    is_platform_kefu = False
    if user and user.role:
        is_platform_kefu = user.role.code == "platform_kefu"
    
    if not is_platform_kefu:
        raise HTTPException(status_code=403, detail="只有平台客服可以删除房间")
    
    # 获取房间
    room = db.query(ChatRoom).filter(ChatRoom.room_id == room_id).first()
    if not room:
        raise HTTPException(status_code=404, detail="房间不存在")
    
    # 软删除：将is_active设置为False
    room.is_active = False
    db.commit()
    
    # 清理Redis缓存
    try:
        redis_client = get_redis()
        # 删除历史消息缓存
        redis_key = f"chat_history:{room_id}"
        redis_client.delete(redis_key)
        
        # 从所有客服的在线用户列表中移除
        from Models.login.models import Role
        platform_kefu_role = db.query(Role).filter(Role.code == "platform_kefu").first()
        kefu_list = []
        if platform_kefu_role:
            kefu_users = db.query(User).filter(User.role_id == platform_kefu_role.id).all()
            kefu_list = [kefu.id for kefu in kefu_users]
        else:
            kefu_role = db.query(Role).filter(Role.code == "kefu").first()
            if kefu_role:
                kefu_users = db.query(User).filter(User.role_id == kefu_role.id).all()
                kefu_list = [kefu.id for kefu in kefu_users]
        
        # 如果房间有分配的客服，也从该客服的列表中移除
        if room.kefu_id:
            kefu_list.append(room.kefu_id)
        
        # 从所有相关客服的在线用户列表中移除
        for kefu_id in set(kefu_list):
            online_users_key = f"kefu_online_users_{kefu_id}"
            redis_client.srem(online_users_key, room_id)
        
        logger.info(f"平台客服 {user_id} 删除房间 {room_id}，已清理Redis缓存")
    except Exception as e:
        logger.error(f"清理Redis缓存失败: {e}")
    
    return {"message": "房间已删除", "room_id": room_id}

